package org.reborn.engine.util


/**
 * A Registry is a collection that maintains an id -> object relationship.
 * Objects are registered in the Registry and are automatically given an id
 * for later retrieval or to unregister the object.
 * 
 * IDs are guaranteed to be unique, so one id maps to one object, much like
 * a Map[Int,T] where T is the type of the object.
 * 
 * The inverse is also true, where registered objects are unique.  There is 
 * a one-to-one mapping between registration IDs and their corresponding objects.
 */
trait Registry[T]{
  
  /**
   * Registers an object and returns a registration ID.
   * 
   * If the same object is already registered, InvalidRegistrationException 
   * will be thrown. Same-ness is defined by the equals operator of type T
   */
  def register(obj:T):Int;
  
  /**
   * Unregisters an object from the registry.  If an id is passed in that
   * is not in the registry, the state of the registry remains unchanged.
   */
  def unregister(id:Int):Unit;
  
  /**
   * Returns the object that was registered with id.  If id is not registered,
   * the empty Option (None) is returned
   */
  def get(id:Int):Option[T];
  
  /**
   * Returns the object that was registered with id.  If id is not registered,
   * the empty Option (None) is returned
   */
  def reregister(id:Int,obj:T):Unit;
}

/**
 * Convenience methods for creating various types of registries.
 */
object Registry{
  
  /**
   * Instantiates and returns a SimpleRegistry
   */
  def SimpleRegistry[T] = new SimpleRegistry[T]();
  
  /**
   * Instantiates and returns a ActorBasedRegistry
   */
 // def ConcurrentRegistry[T] = new ActorBasedRegistry[T]();
}

class RegistryException(message:String) extends Exception(message);
